#pragma once
#include <PSDFCore/PSDFCore.h>
#include <decl.h>

const string INFRARED_VIEW = "Infrared view";

typedef unsigned char byte;

inline unsigned int GLOBALCONFIG_DECL MISSILES_DATA_UPDATE_func()
{
	static unsigned int n = generateCustomEventGroup();
	return n;
}
#define MISSILES_DATA_UPDATE MISSILES_DATA_UPDATE_func()


struct EnemyMissileInfo
{
	string	name;			// 导弹名
	float	speed;			// 刚进入中段飞行时的速度(千米/秒)
	short	baitCount;		// 诱饵个数
	string	modelFile;		// 模型文件

	EnemyMissileInfo() : name("新弹道导弹"), speed(0), baitCount(0), modelFile("default_dt.ive") {}
};

struct OurMissileInfo
{
	string	name;			// 导弹名
	float	speed;			// 刚进入中段飞行时的速度(千米/秒)
	float	angleRate;		// 制导时的旋转角速度(度/秒)
	string	modelFile;		// 模型文件

	OurMissileInfo() : name("新拦截弹"), speed(0), angleRate(10), modelFile("default_missile.ive") {}
};

struct Address
{
	string	name;
	float	lon;
	float	lat;

	Address() : name("新地点"), lon(0), lat(0) {}
};

struct GLOBALCONFIG_DECL Situation
{
	unsigned int id;
	unsigned int nextId()
	{
		static unsigned totalId = 0;
		return ++totalId;
	}

// 敌方导弹
	struct
	{
		EnemyMissileInfo*	missile;
		Address*			addr;			// 地点
		float				alt;			// 刚进入中段飞行时的高度
		float				thetaEarth;		// 刚进入中段飞行时相对地平面的仰角(度, (0, 90))
		float				thetaNorth;		// 刚进入中段飞行时相对正北的偏角(度, (-180, 180]，向东为正)
	} enemy;

// 我方导弹
	struct
	{
		OurMissileInfo*	missile;
		Address*		addr;			// 地点
		float			alt;			// 刚进入中段飞行时的高度
		float			thetaEarth;		// 刚进入中段飞行时相对地平面的仰角(度)
		float			thetaNorth;		// 刚进入中段飞行时相对正北的偏角(度)
		float			delayTime;	 	// 当敌方导弹进入中段飞行多久(秒)后，我方导弹进入中段飞行
	} our;

// 红外探测器
	struct
	{
		float	cameraAngle;	// 红外相机的视场角(度)
		short	resolution;		// 红外相机的分辨率(正方形，边长像素数）
		float	blindRate;		// 盲元率(%)
		byte	updateRate;		// 成像速率(成像数/秒)
	} infrared;

// 其他
	struct 
	{
		bool	saveToFile;
		//wchar_t savePath[200];
		float	distForStartInfr;
	} other;

	Situation()
	{
		memset(this, 0, sizeof(Situation));
		id = nextId();
	}
	Situation(unsigned int id)
	{
		memset(this, 0, sizeof(Situation));
		this->id = id;
		while (nextId() >= id);
	}

	bool isValid()
	{
		if (enemy.missile == NULL) { return false; }
		if (enemy.addr == NULL) { return false; }
		if (enemy.thetaEarth <= 0 || enemy.thetaEarth >= 90) { return false; }
		if (enemy.missile->speed <= 0 || enemy.missile->speed >= 10) { return false; }
		if (our.missile == NULL) { return false; }
		if (our.addr == NULL) { return false; }
		if (our.thetaEarth <= 0 || enemy.thetaEarth >= 90) { return false; }
		if (our.missile->speed <= 0 || our.missile->speed >= 90) { return false; }
		if (our.missile->angleRate <= 0 || our.missile->angleRate >= 360) { return false; }
		if (infrared.cameraAngle <= 0 || infrared.cameraAngle >= 90) { return false; }
		if (infrared.resolution <= 0 || infrared.resolution > 512) { return false; }
		if (infrared.updateRate <= 0 || infrared.updateRate >= 500) { return false; }

		return true;
	}
};

struct MissileData
{
	float currTime;
	double distance;
};



class GLOBALCONFIG_DECL DataManager
{
public:
	static void					loadData();
	static void					saveData();

	static unsigned int			getPresetCount();
	static Situation*			getPreset(unsigned int index);
	static void					newPresetAndMakeCurrent();
	static void					delPreset(unsigned int index);
	static vector<int>			findPresets(const Situation& cond);

	static unsigned int			getAddressCount();
	static Address*				getAddress(unsigned int index);
	static unsigned int			newAddress();
	static void					delAddress(unsigned int index);

	static unsigned int			getEnemyMissileCount();
	static EnemyMissileInfo*	getEnemyMissile(unsigned int index);
	static unsigned int			newEnemyMissile();
	static void					delEnemyMissile(unsigned int index);

	static unsigned int			getOurMissileCount();
	static OurMissileInfo*		getOurMissile(unsigned int index);
	static unsigned int			newOurMissile();
	static void					delOurMissile(unsigned int index);

	static Situation*			getCurrSituation();
	static void					setCurrSituation(unsigned int indexInPresets);

	static unsigned int			findAddressIndex(Address* addr);
	static unsigned int			findOurMissileIndex(OurMissileInfo* missile);
	static unsigned int			findEnemyMissileIndex(EnemyMissileInfo* missile);

private:
	static unsigned int				_currSituationIndex;
	static vector<Situation>		_presets;
	static vector<Address>			_addrs;
	static vector<EnemyMissileInfo>	_enemyMissiles;
	static vector<OurMissileInfo>	_ourMissiles;
};

#ifdef _WIN32
#  ifndef GLOBALCONFIG_EXPORTS
#    ifdef _DEBUG
#      pragma comment(lib, "GlobalConfigd.lib")
#    else
#      pragma comment(lib, "GlobalConfig.lib")
#    endif
#  endif
#endif
